/**
 * 评论数据模型
 * @author HalRui
 * @version 1.0.0
 * @description 基于Mongoose的评论数据模型，定义评论数据结构、验证规则和操作方法，支持多级评论和软删除
 * @date 2025年9月27日
 */

const mongoose = require("mongoose");

// 评论ID计数器模型
const CommentIdCounterSchema = new mongoose.Schema({
    _id: { type: String, required: true },
    sequence_value: { type: Number, default: 0 }
});

const CommentIdCounter = mongoose.model('CommentIdCounter', CommentIdCounterSchema);

// 评论模型
const CommentSchema = new mongoose.Schema({
    commentId: {
        type: Number,
        unique: true,
        index: true,
        description: "全局唯一自增评论ID"
    },
    videoID: {
        type: Number,
        required: true,
        index: true,
        description: "关联的视频ID"
    },
    userId: {
        type: Number,
        required: true,
        index: true,
        description: "评论用户ID"
    },
    parentId: {
        type: Number,
        default: 0,  // 0代表是一级评论
        index: true,
        description: "父评论ID，0表示一级评论"
    },
    content: {
        type: String,
        required: true,
        trim: true,
        maxlength: 500,
        description: "评论内容"
    },
    likeNumber: {
        type: Number,
        default: 0,
        min: 0,
        description: "点赞数"
    },
    unlikeNumber: {
        type: Number,
        default: 0,
        min: 0,
        description: "点踩数"
    },
    replyCount: {
        type: Number,
        default: 0,
        min: 0,
        description: "回复数量"
    },
    status: {
        type: Number,
        default: 1, // 1是正常状态  0是禁用
        index: true,
        description: "评论状态：1-正常，0-禁用"
    },
    isDeleted: {
        type: Boolean,
        default: false,
        index: true,
        description: "是否已删除（软删除）"
    },
    deletedAt: {
        type: Date,
        description: "删除时间"
    },
    createAt: {
        type: Date,
        default: Date.now,
        description: "创建时间"
    },
    updateAt: {
        type: Date,
        default: Date.now,
        description: "更新时间"
    },
    ip: {
        type: String,
        trim: true,
        description: "用户IP地址"
    }
}, {
    versionKey: false // 禁用 __v
});

// 设置commentId的自增
CommentSchema.pre("save", async function (next) {
    if (this.isNew && !this.commentId) {
        try {
            const counter = await CommentIdCounter.findByIdAndUpdate(
                'commentId',
                { $inc: { sequence_value: 1 } },
                { new: true, upsert: true, setDefaultsOnInsert: true }
            );
            this.commentId = counter.sequence_value;
        } catch (error) {
            return next(error);
        }
    }

    // 更新更新时间
    if (this.isModified()) {
        this.updateAt = new Date();
    }

    next();
});

// === 静态方法 ===

/**
 * 创建评论
 * @param {Object} commentData
 * @returns {Object} { success, comment, error }
 */
CommentSchema.statics.createComment = async function(commentData) {
    try {
        const comment = new this(commentData);
        await comment.save();

        // 如果是回复评论，更新父评论的回复数量
        if (comment.parentId !== 0) {
            await this.findOneAndUpdate(
                { commentId: comment.parentId },
                { $inc: { replyCount: 1 } }
            );
        }

        return { success: true, comment };
    } catch (error) {
        console.error('[CommentModel] 创建评论失败:', error);
        return {
            success: false,
            error: error.message,
            code: error.name === 'ValidationError' ? 'VALIDATION_ERROR' : 'DB_ERROR'
        };
    }
};

/**
 * 根据视频ID查询评论（支持分页和层级结构）
 * @param {number} videoID
 * @param {number} page - 页码（从1开始）
 * @param {number} limit - 每页数量
 * @param {number} parentId - 父评论ID，默认为0（一级评论）
 * @returns {Promise<Object>} 包含分页信息的结果
 */
CommentSchema.statics.findByVideoID = async function(videoID, page = 1, limit = 20, parentId = 0) {
    const skip = (page - 1) * limit;
    const query = {
        videoID,
        parentId,
        status: 1,
        isDeleted: false
    };

    const [comments, total] = await Promise.all([
        this.find(query)
            .sort({ likeNumber: -1, createAt: -1 }) // 按点赞数和时间排序
            .skip(skip)
            .limit(limit)
            .lean(),
        this.countDocuments(query)
    ]);

    return {
        comments,
        pagination: {
            page,
            limit,
            total,
            pages: Math.ceil(total / limit),
            hasMore: skip + comments.length < total
        }
    };
};

/**
 * 根据用户ID查询评论
 * @param {number} userId
 * @param {number} page - 页码
 * @param {number} limit - 每页数量
 * @returns {Promise<Object>} 包含分页信息的结果
 */
CommentSchema.statics.findByUserId = async function(userId, page = 1, limit = 20) {
    const skip = (page - 1) * limit;
    const query = {
        userId,
        status: 1,
        isDeleted: false
    };

    const [comments, total] = await Promise.all([
        this.find(query)
            .sort({ createAt: -1 })
            .skip(skip)
            .limit(limit)
            .lean(),
        this.countDocuments(query)
    ]);

    return {
        comments,
        pagination: {
            page,
            limit,
            total,
            pages: Math.ceil(total / limit),
            hasMore: skip + comments.length < total
        }
    };
};

/**
 * 增加评论点赞数
 * @param {number} commentId
 * @returns {Promise<Object|null>} 更新后的评论
 */
CommentSchema.statics.increaseLike = async function(commentId) {
    return await this.findOneAndUpdate(
        { commentId, status: 1, isDeleted: false },
        {
            $inc: { likeNumber: 1 },
            updateAt: new Date()
        },
        { new: true }
    );
};

/**
 * 增加评论点踩数
 * @param {number} commentId
 * @returns {Promise<Object|null>} 更新后的评论
 */
CommentSchema.statics.increaseUnlike = async function(commentId) {
    return await this.findOneAndUpdate(
        { commentId, status: 1, isDeleted: false },
        {
            $inc: { unlikeNumber: 1 },
            updateAt: new Date()
        },
        { new: true }
    );
};

/**
 * 软删除评论
 * @param {number} commentId
 * @param {number} userId - 操作者用户ID（用于权限验证）
 * @returns {Promise<Object|null>} 更新后的评论
 */
CommentSchema.statics.softDelete = async function(commentId, userId = null) {
    const updateData = {
        isDeleted: true,
        deletedAt: new Date(),
        status: 0,
        updateAt: new Date()
    };

    // 如果提供了userId，验证评论归属
    const query = userId
        ? { commentId, userId, isDeleted: false }
        : { commentId, isDeleted: false };

    return await this.findOneAndUpdate(
        query,
        updateData,
        { new: true }
    );
};

/**
 * 禁用评论（管理员操作）
 * @param {number} commentId
 * @returns {Promise<Object|null>} 更新后的评论
 */
CommentSchema.statics.disableComment = async function(commentId) {
    return await this.findOneAndUpdate(
        { commentId, isDeleted: false },
        {
            status: 0,
            updateAt: new Date()
        },
        { new: true }
    );
};

/**
 * 启用评论（管理员操作）
 * @param {number} commentId
 * @returns {Promise<Object|null>} 更新后的评论
 */
CommentSchema.statics.enableComment = async function(commentId) {
    return await this.findOneAndUpdate(
        { commentId, isDeleted: false },
        {
            status: 1,
            updateAt: new Date()
        },
        { new: true }
    );
};

/**
 * 获取评论统计信息
 * @param {number} videoID
 * @returns {Promise<Object>} 评论统计
 */
CommentSchema.statics.getCommentStats = async function(videoID) {
    const stats = await this.aggregate([
        {
            $match: {
                videoID,
                status: 1,
                isDeleted: false,
                parentId: 0 // 只统计一级评论
            }
        },
        {
            $group: {
                _id: null,
                totalComments: { $sum: 1 },
                totalLikes: { $sum: "$likeNumber" },
                totalUnlikes: { $sum: "$unlikeNumber" },
                totalReplies: { $sum: "$replyCount" }
            }
        }
    ]);

    return stats[0] || {
        totalComments: 0,
        totalLikes: 0,
        totalUnlikes: 0,
        totalReplies: 0
    };
};

// === 实例方法 ===

/**
 * 获取安全的JSON对象（用于API响应）
 * @returns {Object} 脱敏后的评论数据
 */
CommentSchema.methods.getSafeJSON = function() {
    const obj = this.toObject();
    const { ip, __v, ...safe } = obj;
    return safe;
};

/**
 * 检查评论是否可编辑（基于时间限制等）
 * @returns {boolean} 是否可编辑
 */
CommentSchema.methods.canEdit = function() {
    // 假设评论发布后30分钟内可编辑
    const editTimeLimit = 30 * 60 * 1000; // 30分钟
    return (Date.now() - this.createAt.getTime()) < editTimeLimit;
};

/**
 * 更新评论内容
 * @param {string} newContent
 * @returns {Promise<boolean>} 是否更新成功
 */
CommentSchema.methods.updateContent = async function(newContent) {
    if (!this.canEdit()) {
        throw new Error('评论已超过可编辑时间');
    }

    this.content = newContent;
    this.updateAt = new Date();
    await this.save();
    return true;
};

// === 导出模型 ===
module.exports = mongoose.model("Comment", CommentSchema);